<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Title</title>
</head>
<body>

</body>
<script>
	// 1- 值类型赋值是深复制还是浅复制
	// 答：严格意义而言，值类型赋值是没有深复制与浅复制的区别的。那么是深复制。
	// let a = 1;
	// let b = a;
	// console.log(a === b);// true
	// console.log(a,b);// 1 1
	// b = 100;
	// console.log(a === b);// false
	// console.log(a,b);// 1 100;
	
	// 2- 深复制以及浅复制都是针对引用类型而言的。
	// 2-1- 简单引用类型以下为深复制
	// const arr = [1,2,3,4];
	// // 数组深复制1：
	// const arr2 = [...arr];
	// console.log(arr === arr2);// false
	// console.log(arr,arr2);
	// arr2.push(5);
	// console.log(arr,arr2);
	// // 数组深复制2：
	// const arr3 = arr.map(item=>item);
	// // 数组深复制3：
	// const arr4 = Array.from(arr);
	// console.log(arr,arr4);
	// arr4.push(100);
	// console.log(arr);
	// // 数组深复制4：
	// const arr5 = [].concat(arr);
	//
	// const obj = {
	// 	a:1,
	// 	b:2,
	// 	c:3
	// }
	// // 对象深复制1：
	// const obj2 = {...obj};
	// obj2.a = 100;
	// console.log(obj);
	// // 对象深复制2：
	// const obj3 = Object.assign({},obj);
	// obj3.a = 200;
	// console.log(obj);
	
	// 2-2- 引用类型如果直接赋值为浅复制
	// const arr = [1,2,3,4];
	// const arr2 = arr;
	// // console.log(arr===arr2);
	// arr2.push(100);
	// console.log(arr,arr2);
	//
	// const obj = {
	// 	a:1,
	// 	b:2
	// }
	// const obj2 = obj;
	// console.log(obj === obj2);
	// obj2.a = 100;
	// console.log(obj);
	
	// 2-3- 复杂引用类型：数组-数组的元素中包含引用类型   对象-对象当中的属性包含引用类型
	// 以下为浅复制
	// const arr = [1,2,[3,4],{a:1,b:2}];
	// const arr2 = Array.from(arr);
	// const arr3 = [...arr];
	// const arr4 = [].concat(arr);
	// const arr5 = arr.map(item=>item);
	// console.log(arr === arr2);// false
	// console.log(arr === arr3);// false
	// console.log(arr === arr4);// false
	// console.log(arr === arr5);// false
	// console.log(arr[2] === arr2[2]);
	// console.log(arr[2] === arr3[2]);
	// console.log(arr[2] === arr4[2]);
	// console.log(arr[2] === arr5[2]);
	// console.log(arr[3] === arr2[3]);
	// console.log(arr[3] === arr3[3]);
	// console.log(arr[3] === arr4[3]);
	// console.log(arr[3] === arr5[3]);
	// arr2[2].push(5);
	// arr3[3].c = 200;
	// console.log(arr);
	
	// 实现深复制
	// const arr = [1,2,[3,4],{a:1,b:2}];
	// const arr2 = JSON.parse(JSON.stringify(arr));
	// console.log(arr === arr2);// false
	// console.log(arr[2] === arr2[2]);// false
	// console.log(arr[3] === arr2[3]);// false
	// arr2[3].c = 100;
	// console.log(arr,arr2);
	
	// 以上实现深复制的问题
	// const obj = {
	// 	a:1,
	// 	b:2,
	// 	c:3,
	// 	d:undefined,
	// 	e:null,
	// 	f:function(){
	// 		console.log("f")
	// 	},
	// 	m:{
	// 		a:1,
	// 		b:2
	// 	}
	// }
	// const obj2 = JSON.parse(JSON.stringify(obj));
	// console.log(obj2 === obj);// false
	// obj2.c = 300;
	// console.log(obj2);
	
	// 通过自定义函数实现深复制
	const obj = {
		a:1,
		b:[1,2,[3,4],{userName:"zhangsan",age:12}],
		c:{
			id:1,
			info:{
				m:2,
				n:0
			}
		}
	}
	function deepClone(source){
		const copySource = Array.isArray(source)?[]:{};
		for(let key in source){
			if(source[key] && typeof source[key] === "object"){
				copySource[key] = deepClone(source[key]);
			}else
				copySource[key] = source[key];
		}
		return copySource;
	}
	const obj2 = deepClone(obj);
	console.log(obj === obj2);
	console.log(obj2.c.id = 100);
	console.log(obj2)
	
	// 以下算深复制，但不要这样写，不够灵活，只是针对同样的引用类型而言，换一个其它的引用类型不起作用
	// const obj2 = {...obj};
	// obj2.b[2] = [...obj.b[2]];
	// obj2.b[3] = {...obj.b[3]};
	// obj2.c = {...obj.c};
	// obj2.c.info = {...obj.c.info}
	
	
	
	
	
</script>
</html>